/**
 ******************************************************************************
 * @file           : ring_buffer.c
 * @brief          : Ring Buffer Implementation
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "ring_buffer.h"
#include <string.h>

/* Exported functions --------------------------------------------------------*/

/**
 * @brief       初始化环形缓冲区
 *
 * @param[in]   rb: 环形缓冲区指针
 * @param[in]   buffer: 缓冲区数组
 * @param[in]   size: 缓冲区大小
 */
void ring_buffer_init(RingBuffer_t *rb, uint8_t *buffer, uint32_t size)
{
    if (rb == NULL || buffer == NULL || size == 0)
    {
        return;
    }
    
    rb->buffer = buffer;
    rb->size = size;
    rb->head = 0;
    rb->tail = 0;
    rb->count = 0;
}

/**
 * @brief       复位环形缓冲区
 */
void ring_buffer_reset(RingBuffer_t *rb)
{
    if (rb == NULL)
    {
        return;
    }
    
    rb->head = 0;
    rb->tail = 0;
    rb->count = 0;
}

/**
 * @brief       写入单个字节
 *
 * @param[in]   rb: 环形缓冲区指针
 * @param[in]   data: 数据
 *
 * @retval      true=成功, false=缓冲区满
 */
bool ring_buffer_put(RingBuffer_t *rb, uint8_t data)
{
    if (rb == NULL || ring_buffer_is_full(rb))
    {
        return false;
    }
    
    rb->buffer[rb->head] = data;
    rb->head = (rb->head + 1) % rb->size;
    rb->count++;
    
    return true;
}

/**
 * @brief       写入多个字节
 *
 * @param[in]   rb: 环形缓冲区指针
 * @param[in]   data: 数据数组
 * @param[in]   len: 数据长度
 *
 * @retval      实际写入的字节数
 */
uint32_t ring_buffer_write(RingBuffer_t *rb, const uint8_t *data, uint32_t len)
{
    uint32_t i;
    uint32_t written = 0;
    
    if (rb == NULL || data == NULL)
    {
        return 0;
    }
    
    for (i = 0; i < len; i++)
    {
        if (ring_buffer_put(rb, data[i]))
        {
            written++;
        }
        else
        {
            break;  /* 缓冲区满 */
        }
    }
    
    return written;
}

/**
 * @brief       读取单个字节
 *
 * @param[in]   rb: 环形缓冲区指针
 * @param[out]  data: 数据指针
 *
 * @retval      true=成功, false=缓冲区空
 */
bool ring_buffer_get(RingBuffer_t *rb, uint8_t *data)
{
    if (rb == NULL || data == NULL || ring_buffer_is_empty(rb))
    {
        return false;
    }
    
    *data = rb->buffer[rb->tail];
    rb->tail = (rb->tail + 1) % rb->size;
    rb->count--;
    
    return true;
}

/**
 * @brief       读取多个字节
 *
 * @param[in]   rb: 环形缓冲区指针
 * @param[out]  data: 数据数组
 * @param[in]   len: 读取长度
 *
 * @retval      实际读取的字节数
 */
uint32_t ring_buffer_read(RingBuffer_t *rb, uint8_t *data, uint32_t len)
{
    uint32_t i;
    uint32_t read = 0;
    
    if (rb == NULL || data == NULL)
    {
        return 0;
    }
    
    for (i = 0; i < len; i++)
    {
        if (ring_buffer_get(rb, &data[i]))
        {
            read++;
        }
        else
        {
            break;  /* 缓冲区空 */
        }
    }
    
    return read;
}

/**
 * @brief       查看数据（不移除）
 *
 * @param[in]   rb: 环形缓冲区指针
 * @param[out]  data: 数据指针
 *
 * @retval      true=成功, false=缓冲区空
 */
bool ring_buffer_peek(RingBuffer_t *rb, uint8_t *data)
{
    if (rb == NULL || data == NULL || ring_buffer_is_empty(rb))
    {
        return false;
    }
    
    *data = rb->buffer[rb->tail];
    return true;
}

/**
 * @brief       查看指定偏移的数据
 *
 * @param[in]   rb: 环形缓冲区指针
 * @param[in]   offset: 偏移量（0=第一个数据）
 * @param[out]  data: 数据指针
 *
 * @retval      实际查看的字节数
 */
uint32_t ring_buffer_peek_at(RingBuffer_t *rb, uint32_t offset, uint8_t *data)
{
    uint32_t index;
    
    if (rb == NULL || data == NULL || offset >= rb->count)
    {
        return 0;
    }
    
    index = (rb->tail + offset) % rb->size;
    *data = rb->buffer[index];
    
    return 1;
}

/**
 * @brief       检查缓冲区是否为空
 */
bool ring_buffer_is_empty(RingBuffer_t *rb)
{
    if (rb == NULL)
    {
        return true;
    }
    
    return (rb->count == 0);
}

/**
 * @brief       检查缓冲区是否已满
 */
bool ring_buffer_is_full(RingBuffer_t *rb)
{
    if (rb == NULL)
    {
        return true;
    }
    
    return (rb->count >= rb->size);
}

/**
 * @brief       获取可用数据量
 */
uint32_t ring_buffer_available(RingBuffer_t *rb)
{
    if (rb == NULL)
    {
        return 0;
    }
    
    return rb->count;
}

/**
 * @brief       获取剩余空间
 */
uint32_t ring_buffer_free_space(RingBuffer_t *rb)
{
    if (rb == NULL)
    {
        return 0;
    }
    
    return (rb->size - rb->count);
}

/**
 * @brief       查找数据
 *
 * @param[in]   rb: 环形缓冲区指针
 * @param[in]   data: 要查找的数据
 *
 * @retval      数据位置（-1=未找到）
 */
int32_t ring_buffer_find(RingBuffer_t *rb, uint8_t data)
{
    uint32_t i, index;
    
    if (rb == NULL || ring_buffer_is_empty(rb))
    {
        return -1;
    }
    
    for (i = 0; i < rb->count; i++)
    {
        index = (rb->tail + i) % rb->size;
        
        if (rb->buffer[index] == data)
        {
            return (int32_t)i;
        }
    }
    
    return -1;
}

/**
 * @brief       查找字符串
 *
 * @param[in]   rb: 环形缓冲区指针
 * @param[in]   str: 要查找的字符串
 *
 * @retval      字符串位置（-1=未找到）
 */
int32_t ring_buffer_find_string(RingBuffer_t *rb, const char *str)
{
    uint32_t i, j, index;
    uint32_t str_len;
    bool found;
    
    if (rb == NULL || str == NULL || ring_buffer_is_empty(rb))
    {
        return -1;
    }
    
    str_len = strlen(str);
    
    if (str_len > rb->count)
    {
        return -1;
    }
    
    /* 遍历缓冲区 */
    for (i = 0; i <= rb->count - str_len; i++)
    {
        found = true;
        
        /* 比较字符串 */
        for (j = 0; j < str_len; j++)
        {
            index = (rb->tail + i + j) % rb->size;
            
            if (rb->buffer[index] != (uint8_t)str[j])
            {
                found = false;
                break;
            }
        }
        
        if (found)
        {
            return (int32_t)i;
        }
    }
    
    return -1;
}
